"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const _hoisted_1 = { class: "me-roll-inner" };
const _hoisted_2 = ["data-id"];
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  ...{
    name: "me-roll"
  },
  __name: "roll",
  props: {
    direction: { default: "vertical" },
    speed: { default: 1 },
    list: { default() {
      return [];
    } },
    loop: { type: Boolean, default: false },
    duration: { default: 1e3 },
    interval: { default: 2e3 },
    rows: { default: 1 },
    intervalAnimation: { type: Boolean, default: false }
  },
  setup(__props) {
    const props = __props;
    const rollRef = vue.ref();
    const isHover = vue.ref(false);
    const arrayList = vue.ref([]);
    let requestId;
    let moveCount = 0;
    let timerId1;
    let timerId2;
    let timerId3;
    const isAnimating = vue.ref(false);
    const handleIntersection = (entries) => {
      const entry = entries[0];
      if (!entry.isIntersecting && !isHover.value) {
        const deleteItem = arrayList.value.splice(0, 1);
        arrayList.value.push(deleteItem[0]);
        if (props.direction === "horizontal") {
          rollRef.value.scrollLeft -= entry.target.clientWidth;
        }
        vue.nextTick(() => {
          updateListPosition();
        });
      }
    };
    const observer = new IntersectionObserver(handleIntersection, {
      root: rollRef.value
    });
    vue.watch(isAnimating, () => {
      const { direction } = props;
      if (!isAnimating.value) {
        initList();
        stopIntervalAnimationMove();
        vue.nextTick(() => {
          initListPosition();
          startIntervalAnimationMove(direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft);
        });
      }
    });
    vue.watch(() => props.list, () => {
      const { loop, intervalAnimation } = props;
      if (!intervalAnimation) {
        initList();
        stopMove();
        loop && stopObserver();
        vue.nextTick(() => {
          startMove();
          initListPosition();
          loop && startObserver();
        });
      }
    }, { deep: true });
    vue.watch(() => props.direction, () => {
      moveCount = 0;
      isHover.value = false;
      stopMove();
      stopObserver();
      stopIntervalAnimationMove();
      initList();
      vue.nextTick(() => {
        initListPosition();
        startMove();
        startObserver();
      });
    });
    vue.onMounted(() => {
      initList();
      vue.nextTick(() => {
        initListPosition();
        startMove();
        startObserver();
      });
    });
    vue.onBeforeUnmount(() => {
      stopObserver();
      requestId && cancelAnimationFrame(requestId);
      timerId1 && clearTimeout(timerId1);
      timerId2 && clearTimeout(timerId2);
      timerId3 && clearTimeout(timerId3);
    });
    const startObserver = () => {
      const { loop, intervalAnimation } = props;
      if (loop && !intervalAnimation) {
        const doms = rollRef.value.getElementsByClassName("me-roll-item");
        for (const dom of doms) {
          observer.observe(dom);
        }
      }
    };
    const stopObserver = () => {
      const { loop, intervalAnimation } = props;
      if (loop && !intervalAnimation) {
        const doms = rollRef.value.getElementsByClassName("me-roll-item");
        for (const dom of doms) {
          observer.unobserve(dom);
        }
      }
    };
    const updateListPosition = () => {
      const { direction } = props;
      const doms = rollRef.value.getElementsByClassName("me-roll-item");
      const parentOffset = direction === "vertical" ? rollRef.value.offsetTop : rollRef.value.offsetLeft;
      for (const dom of doms) {
        const id = dom.getAttribute("data-id");
        const top = direction === "vertical" ? dom.offsetTop : dom.offsetLeft;
        for (const item of arrayList.value) {
          if (item.rollId === id) {
            item.top = top - parentOffset;
            break;
          }
        }
      }
    };
    const initListPosition = () => {
      const { direction } = props;
      const doms = rollRef.value.getElementsByClassName("me-roll-item");
      const parentOffset = direction === "vertical" ? rollRef.value.offsetTop : rollRef.value.offsetLeft;
      for (let i = 0; i < doms.length; i++) {
        const dom = doms[i];
        const offset = direction === "vertical" ? dom.offsetTop : dom.offsetLeft;
        const rect = dom.getBoundingClientRect();
        const height = direction === "vertical" ? rect.height : rect.width;
        arrayList.value[i].top = offset - parentOffset;
        arrayList.value[i].height = height;
      }
    };
    const startMove = () => {
      const { intervalAnimation } = props;
      if (intervalAnimation) {
        startIntervalAnimationMove(getDistance());
      } else {
        startUniformSpeedMove();
      }
    };
    const getDistance = () => {
      const { rows } = props;
      let height = 0;
      const list = arrayList.value.slice(rows * moveCount, (moveCount + 1) * rows);
      list.map((item) => {
        height += item.height;
      });
      return height;
    };
    const startIntervalAnimationMove = (defaultOffset) => {
      const { interval, duration, direction } = props;
      const scrollHeight = direction === "vertical" ? rollRef.value.scrollHeight : rollRef.value.scrollWidth;
      const rect = rollRef.value.getBoundingClientRect();
      const height = direction === "vertical" ? rect.height : rect.width;
      const scrollTop = scrollHeight - height;
      let distance = defaultOffset;
      let allHeight = distance;
      let speed = distance / duration * 16;
      const move = () => {
        const offset = direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft;
        if (offset >= allHeight) {
          direction === "vertical" ? rollRef.value.scrollTop = allHeight : rollRef.value.scrollLeft = allHeight;
          isAnimating.value = false;
          requestId && cancelAnimationFrame(requestId);
          timerId1 = setTimeout(() => {
            moveCount++;
            ;
            distance = getDistance();
            allHeight += distance;
            speed = distance / duration * 16;
            move();
          }, interval);
          return;
        }
        isAnimating.value = true;
        if ((direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft) >= scrollTop) {
          let topId;
          let speed2 = offset / duration * 16;
          const goTop = () => {
            direction === "vertical" ? rollRef.value.scrollTop -= speed2 : rollRef.value.scrollLeft -= speed2;
            if ((direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft) <= 0) {
              topId && cancelAnimationFrame(topId);
              direction === "vertical" ? rollRef.value.scrollTop = 0 : rollRef.value.scrollLeft = 0;
              timerId3 = setTimeout(() => {
                moveCount = 0;
                allHeight = 0;
                startIntervalAnimationMove(getDistance());
              }, interval);
              return;
            }
            topId = requestAnimationFrame(goTop);
          };
          timerId2 = setTimeout(() => {
            goTop();
          }, interval);
          return;
        }
        direction === "vertical" ? rollRef.value.scrollTop += speed : rollRef.value.scrollLeft += speed;
        requestId = requestAnimationFrame(move);
      };
      move();
    };
    const startUniformSpeedMove = () => {
      const { speed, loop, direction } = props;
      const scrollHeight = direction === "vertical" ? rollRef.value.scrollHeight : rollRef.value.scrollWidth;
      const rect = rollRef.value.getBoundingClientRect();
      const height = direction === "vertical" ? rect.height : rect.width;
      const scrollTop = scrollHeight - height;
      const move = () => {
        if (!loop) {
          if ((direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft) >= scrollTop) {
            direction === "vertical" ? rollRef.value.scrollTop = 0 : rollRef.value.scrollLeft = 0;
          }
        }
        direction === "vertical" ? rollRef.value.scrollTop += speed : rollRef.value.scrollLeft += speed;
        requestId = requestAnimationFrame(move);
      };
      move();
    };
    const initList = () => {
      const { list } = props;
      arrayList.value = [];
      list.forEach((item, index) => {
        arrayList.value.push({
          ...item,
          rollId: item.id || Math.random().toString(16),
          index,
          top: 0
        });
      });
    };
    const stopMove = () => {
      requestId && cancelAnimationFrame(requestId);
    };
    const stopIntervalAnimationMove = () => {
      requestId && cancelAnimationFrame(requestId);
      timerId1 && clearTimeout(timerId1);
      timerId2 && clearTimeout(timerId2);
      timerId3 && clearTimeout(timerId3);
    };
    const onMouseenter = () => {
      const { intervalAnimation } = props;
      isHover.value = true;
      if (intervalAnimation) {
        stopIntervalAnimationMove();
      } else {
        stopMove();
      }
    };
    const onMouseleave = () => {
      const { intervalAnimation, rows, duration, direction } = props;
      isHover.value = false;
      if (intervalAnimation) {
        let height = 0;
        for (let i = 0; i < (moveCount + 1) * rows; i++) {
          height += arrayList.value[i].height;
        }
        const scrollTop = direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft;
        const distance = Math.abs(scrollTop - height);
        if (scrollTop > height) {
          const speed = distance / duration * 16;
          const go = () => {
            if ((direction === "vertical" ? rollRef.value.scrollTop : rollRef.value.scrollLeft) <= height) {
              direction === "vertical" ? rollRef.value.scrollTop = height : rollRef.value.scrollLeft = height;
              requestId && cancelAnimationFrame(requestId);
              startIntervalAnimationMove(height);
              return;
            }
            direction === "vertical" ? rollRef.value.scrollTop -= speed : rollRef.value.scrollLeft -= speed;
            requestId = requestAnimationFrame(go);
          };
          go();
        } else {
          startIntervalAnimationMove(height);
        }
      } else {
        startMove();
      }
    };
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("div", {
        class: vue.normalizeClass(["me-roll", {
          [isHover.value ? "enter" : "leave"]: true,
          loop: _ctx.loop && !_ctx.intervalAnimation,
          [_ctx.direction]: true
        }]),
        ref_key: "rollRef",
        ref: rollRef,
        onMouseenter,
        onMouseleave
      }, [
        vue.createElementVNode("div", _hoisted_1, [
          (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(arrayList.value, (item) => {
            return vue.openBlock(), vue.createElementBlock("div", {
              class: "me-roll-item",
              "data-id": item.rollId,
              key: item.rollId
            }, [
              vue.renderSlot(_ctx.$slots, "default", { item })
            ], 8, _hoisted_2);
          }), 128))
        ])
      ], 34);
    };
  }
});
exports.default = _sfc_main;
//# sourceMappingURL=roll.vue2.cjs.map
